﻿using System;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Extension.String;
using TiaoTaoHelper.Http;
using TiaoTaoHelper.Models;
using WalkingTec.Mvvm.Core;

namespace HengTong.Model.Services;

public class AwsTaskService
{
    private readonly ILogger<AwsTaskService> _logger;
    private readonly string _apiUrl;
    private readonly string _accessKey;
    private readonly string _secret;
    private readonly HttpHelper _httpHelper;


    public AwsTaskService(ILogger<AwsTaskService> logger, WTMContext wtm)
    {
        _logger = logger;
        if (!wtm.ConfigInfo.AppSettings.TryGetValue("AwsApiUrl", out var apiUrl))
        {
#if DEBUG
            apiUrl = "http://192.168.252.109:8088/api";
#else
            throw new Exception("未配置AwsApiUrl");
#endif
        }

        _httpHelper = new HttpHelper();
        _apiUrl = apiUrl;
        _accessKey = "aws";
        _secret = "123456";
        var authToken = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($"{_accessKey}:{_secret}"));
        _httpHelper.GetClient().DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authToken);
    }

    /// <summary>
    /// 创建流程
    /// </summary>
    /// <param name="processDefId">流程定义ID</param>
    /// <param name="uid">用户ID</param>
    /// <param name="title">标题</param>
    /// <param name="processBusinessKey">流程业务键</param>
    /// <param name="createUserDeptId">创建用户部门ID</param>
    /// <param name="createUserRoleId">创建用户角色ID</param>
    /// <param name="vars">变量集合</param>
    /// <returns>流程实例创建结果</returns>
    public async Task<Result<object>> CreateProcessAsync(
        string processDefId,
        string uid,
        string title,
        string processBusinessKey = null,
        string createUserDeptId = null,
        string createUserRoleId = null,
        Dictionary<string, object> vars = null)
    {
        try
        {
            _logger.LogInformation("开始启动流程, processDefId: {ProcessDefId}, uid: {Uid}, title: {title}", processDefId,
                uid, title);

            var httpHelper = _httpHelper;
            var postData = new Dictionary<string, string>
            {
                ["processDefId"] = processDefId,
                ["uid"] = uid,
                ["title"] = title
            };

            if (!string.IsNullOrEmpty(processBusinessKey))
                postData["processBusinessKey"] = processBusinessKey;

            if (!string.IsNullOrEmpty(createUserDeptId))
                postData["createUserDeptId"] = createUserDeptId;

            if (!string.IsNullOrEmpty(createUserRoleId))
                postData["createUserRoleId"] = createUserRoleId;

            if (vars != null)
                postData["vars"] = System.Text.Json.JsonSerializer.Serialize(vars);


            var response = await httpHelper.PostFormAsync($"{_apiUrl}?cmd=process.create", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("启动流程失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<object>("启动流程失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            // 方式1: 使用System.Text.Json配置不区分大小写
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
            if (!content.TryJsonParse(out AwsResponse<object> awsResponse, out var error, options))
            {
                _logger.LogError(error, "启动流程失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<object>("启动流程失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("流程启动成功，响应结果: {Result}", awsResponse.Data);

            return new Result<object>
            {
                Code = 200,
                Message = "流程启动成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "启动流程失败, {Message}", ex.Message);
            return new Result<object>("启动流程失败");
        }
    }

    /// <summary>
    /// 启动流程
    /// </summary>
    /// <param name="processInstId">流程实例ID</param>
    /// <param name="startEventDefId">启动事件定义ID</param>
    /// <returns>流程启动结果</returns>
    public async Task<Result<object>> StartProcessAsync(string processInstId, string startEventDefId = null)
    {
        try
        {
            _logger.LogInformation("开始启动流程实例, processInstId: {ProcessInstId}, startEventDefId: {StartEventDefId}",
                processInstId, startEventDefId);

            var postData = new Dictionary<string, string>
            {
                ["processInstId"] = processInstId,
                ["startEventDefId"] = startEventDefId
            };

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=process.start", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("启动流程实例失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<object>("启动流程实例失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<object> awsResponse, out var error, options))
            {
                _logger.LogError(error, "启动流程实例失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<object>("启动流程实例失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("流程实例启动成功，响应结果: {Result}", awsResponse.Data);

            return new Result<object>
            {
                Code = 200,
                Message = "流程实例启动成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "启动流程实例失败, {Message}", ex.Message);
            return new Result<object>("启动流程实例失败");
        }
    }

    /// <summary>
    /// 获取流程实例信息
    /// </summary>
    /// <param name="processInstId">流程实例ID</param>
    /// <returns>流程实例信息</returns>
    public async Task<Result<object>> GetProcessAsync(string processInstId)
    {
        try
        {
            _logger.LogInformation("开始获取流程实例信息, processInstId: {ProcessInstId}", processInstId);

            var postData = new Dictionary<string, string>
            {
                ["processInstId"] = processInstId
            };

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=process.inst.get", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("获取流程实例信息失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<object>("获取流程实例信息失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<object> awsResponse, out var error, options))
            {
                _logger.LogError(error, "获取流程实例信息失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<object>("获取流程实例信息失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("获取流程实例信息成功，响应结果: {Result}", awsResponse.Data);

            return new Result<object>
            {
                Code = 200,
                Message = "获取流程实例信息成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取流程实例信息失败, {Message}", ex.Message);
            return new Result<object>("获取流程实例信息失败");
        }
    }


    /// <summary>
    /// 完成任务
    /// </summary>
    /// <param name="taskInstId">任务实例ID</param>
    /// <param name="uid">用户ID</param>
    /// <param name="vars">变量集合</param>
    /// <param name="isBranch">是否分支</param>
    /// <param name="isBreakUserTask">是否中断用户任务</param>
    /// <returns>完成任务结果</returns>
    public async Task<Result<object>> CompleteTaskAsync(
        string taskInstId,
        string uid,
        Dictionary<string, object> vars = null,
        bool? isBranch = null,
        bool? isBreakUserTask = null)
    {
        try
        {
            _logger.LogInformation("开始完成任务, taskInstId: {TaskInstId}, uid: {Uid}", taskInstId, uid);

            var postData = new Dictionary<string, string>
            {
                ["taskInstId"] = taskInstId,
                ["uid"] = uid
            };

            if (vars != null)
            {
                postData["vars"] = System.Text.Json.JsonSerializer.Serialize(vars);
            }

            if (isBranch.HasValue)
            {
                postData["isBranch"] = isBranch.Value.ToString().ToLower();
            }

            if (isBreakUserTask.HasValue)
            {
                postData["isBreakUserTask"] = isBreakUserTask.Value.ToString().ToLower();
            }

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=task.complete", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("完成任务失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<object>("完成任务失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<object> awsResponse, out var error, options))
            {
                _logger.LogError(error, "完成任务失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<object>("完成任务失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("任务完成成功，响应结果: {Result}", awsResponse.Data);

            return new Result<object>
            {
                Code = 200,
                Message = "任务完成成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "完成任务失败, {Message}", ex.Message);
            return new Result<object>("完成任务失败");
        }
    }

    /// <summary>
    /// 检查任务是否已关闭
    /// </summary>
    /// <param name="taskInstId">任务实例ID</param>
    /// <returns>任务是否已关闭</returns>
    public async Task<Result<bool>> CheckTaskCloseAsync(string taskInstId)
    {
        try
        {
            _logger.LogInformation("开始检查任务是否已关闭, taskInstId: {TaskInstId}", taskInstId);

            var postData = new Dictionary<string, string>
            {
                ["taskInstId"] = taskInstId
            };

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=task.close.check", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("检查任务是否已关闭失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<bool>("检查任务是否已关闭失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<bool> awsResponse, out var error, options))
            {
                _logger.LogError(error, "检查任务是否已关闭失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<bool>("检查任务是否已关闭失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("检查任务是否已关闭成功，响应结果: {Result}", awsResponse.Data);

            return new Result<bool>
            {
                Code = 200,
                Message = "检查任务是否已关闭成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检查任务是否已关闭失败, {Message}", ex.Message);
            return new Result<bool>("检查任务是否已关闭失败");
        }
    }

    /// <summary>
    /// 检查流程是否已结束
    /// </summary>
    /// <param name="processInstId">流程实例ID</param>
    /// <returns>流程是否已结束</returns>
    public async Task<Result<bool>> CheckProcessEndAsync(string processInstId)
    {
        try
        {
            _logger.LogInformation("开始检查流程是否已结束, processInstId: {ProcessInstId}", processInstId);

            var postData = new Dictionary<string, string>
            {
                ["processInstId"] = processInstId
            };

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=process.end.check", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("检查流程是否已结束失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<bool>("检查流程是否已结束失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<bool> awsResponse, out var error, options))
            {
                _logger.LogError(error, "检查流程是否已结束失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<bool>("检查流程是否已结束失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("检查流程是否已结束成功，响应结果: {Result}", awsResponse.Data);

            return new Result<bool>
            {
                Code = 200,
                Message = "检查流程是否已结束成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检查流程是否已结束失败, {Message}", ex.Message);
            return new Result<bool>("检查流程是否已结束失败");
        }
    }


    /// <summary>
    /// 回滚任务
    /// </summary>
    /// <param name="taskInstId">任务实例ID</param>
    /// <param name="targetActivityId">目标活动ID</param>
    /// <param name="uid">用户ID</param>
    /// <param name="isCompensation">是否补偿</param>
    /// <param name="rollbackReason">回滚原因</param>
    /// <returns>任务回滚结果</returns>
    public async Task<Result<object>> RollbackTaskAsync(
        string taskInstId,
        string targetActivityId,
        string uid,
        bool isCompensation,
        string rollbackReason)
    {
        try
        {
            _logger.LogInformation("开始回滚任务, taskInstId: {TaskInstId}, targetActivityId: {TargetActivityId}, uid: {Uid}",
                taskInstId, targetActivityId, uid);

            var postData = new Dictionary<string, string>
            {
                ["taskInstId"] = taskInstId,
                ["targetActivityId"] = targetActivityId,
                ["uid"] = uid,
                ["isCompensation"] = isCompensation.ToString().ToLower(),
                ["rollbackReason"] = rollbackReason
            };

            var response = await _httpHelper.PostFormAsync($"{_apiUrl}?cmd=task.rollback", postData);

            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("回滚任务失败, 通讯失败, httpStatusCode: {StatusCode}", response.StatusCode);
                return new Result<object>("回滚任务失败, 通讯失败, httpStatusCode: " + response.StatusCode);
            }

            var content = await response.Content.ReadAsStringAsync();
            var options = new System.Text.Json.JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };

            if (!content.TryJsonParse(out AwsResponse<object> awsResponse, out var error, options))
            {
                _logger.LogError(error, "回滚任务失败, JSON解析失败, 错误信息: {Error}", error);
                return new Result<object>("回滚任务失败, JSON解析失败, 错误信息: " + error);
            }

            _logger.LogInformation("任务回滚成功，响应结果: {Result}", awsResponse.Data);

            return new Result<object>
            {
                Code = 200,
                Message = "任务回滚成功",
                Data = awsResponse.Data
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "回滚任务失败, {Message}", ex.Message);
            return new Result<object>("回滚任务失败");
        }
    }
}

public class AwsResponse<T>
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public T Data { get; set; }
}